package com.kwan.xframe;

import android.content.Context;
import android.os.Build;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.WindowManager;

import com.kwan.xframe.crash.LogReport;
import com.kwan.xframe.crash.save.imp.CrashWriter;
import com.kwan.xframe.crash.upload.http.HttpReporter;
import com.orhanobut.logger.AndroidLogAdapter;
import com.orhanobut.logger.FormatStrategy;
import com.orhanobut.logger.Logger;
import com.orhanobut.logger.PrettyFormatStrategy;
import com.scwang.smart.refresh.footer.ClassicsFooter;
import com.scwang.smart.refresh.header.ClassicsHeader;
import com.scwang.smart.refresh.layout.SmartRefreshLayout;
import com.scwang.smart.refresh.layout.api.RefreshFooter;
import com.scwang.smart.refresh.layout.api.RefreshHeader;
import com.scwang.smart.refresh.layout.api.RefreshLayout;
import com.scwang.smart.refresh.layout.listener.DefaultRefreshFooterCreator;
import com.scwang.smart.refresh.layout.listener.DefaultRefreshHeaderCreator;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import androidx.annotation.NonNull;
import androidx.multidex.MultiDexApplication;
import timber.log.Timber;
import uk.co.chrisjenx.calligraphy.CalligraphyConfig;

/**
 * Application 基类
 * Created by Mr.Kwan on 2016-3-30.
 */
public abstract class BaseApplication extends MultiDexApplication {


	//static 代码段可以防止内存泄露
	static {
		//设置全局的Header构建器
		SmartRefreshLayout.setDefaultRefreshHeaderCreator(new DefaultRefreshHeaderCreator() {
			@NonNull
			@Override
			public RefreshHeader createRefreshHeader(@NonNull Context context, @NonNull RefreshLayout layout) {
				//全局设置主题颜色
				layout.setPrimaryColorsId(R.color.colorPrimary, android.R.color.white);
				//.setTimeFormat(new DynamicTimeFormat("更新于 %s"));//指定为经典Header，默认是 贝塞尔雷达Header
				return new ClassicsHeader(context);
			}
		});
		//设置全局的Footer构建器
		SmartRefreshLayout.setDefaultRefreshFooterCreator(new DefaultRefreshFooterCreator() {
			@NonNull
			@Override
			public RefreshFooter createRefreshFooter(@NonNull Context context, @NonNull RefreshLayout layout) {
				//指定为经典Footer，默认是 BallPulseFooter
				return new ClassicsFooter(context).setDrawableSize(20);
			}
		});
	}

	/**
	 * APP实例调用
	 **/
	private static BaseApplication mBaseApplication;
	//private static BaseConfiguration mConfiguration;
	public static int SCREEN_WIDTH;
	public static int SCREEN_HEIGHT;
	public static int STATUS_BAR_HEIGHT;
	public static int TITLE_BAR_HEIGHT;
	//private ImageUtil mImageUtil;
	private Map<String, Integer> mFaceMap = new LinkedHashMap<>();
	private ArrayList<String> mFaceString = new ArrayList<>();
	public static String uniqueId;
	public final String LOG_TAG = "KWAN_TAG";

	public static final String UMENG_APPID = "5aeada7ca40fa3056100002e";

	@Override
	public void onCreate() {
		disableAPIDialog();
		super.onCreate();
		//对单位的自定义配置, 请在 App 启动时完成
		//AutoSizeConfig.getInstance().getUnitsManager()
		//.setSupportDP(false)
		//.setDesignSize(750, 1334)
		//.setSupportSubunits(Subunits.MM);
		mBaseApplication = this;
		initApp();
		initUmeng();
		initCrashHandler();
		//初始化日志框架
		initLogger(LOG_TAG);
		initTsweb();
		initFont();
		initFaceMap();
		initFaceString();
	}

	/**
	 * 安卓9以上的hide api警告对话框，
	 * 各种库大量使用hide api, 无法都解决掉，
	 * 用hide api解决hide api警告，感觉算漏洞，以后可能失效，
	 * <p>
	 * 反射 禁止弹窗
	 */
	@SuppressWarnings("all")
	private void disableAPIDialog() {

		//boolean isSuccess = JJReflection.apiExemptions();
		//Log.e("disableAPIDialog", "reflection isSuccess:" + isSuccess);
//
//		try {
//			ApplicationInfo applicationInfo = this.getApplicationInfo();
//			@SuppressLint({"PrivateApi", "SoonBlockedPrivateApi"})
//			Method hiddenApiEnforcementPolicy = ApplicationInfo.class
//					.getDeclaredMethod("setHiddenApiEnforcementPolicy", int.class);
//			hiddenApiEnforcementPolicy.invoke(applicationInfo, 0);
//			Logger.e("reflection success");
//			Toast.makeText(this, "reflection success", Toast.LENGTH_SHORT).show();
//		} catch (Throwable e) {
//			Logger.e("reflection fail");
//			Toast.makeText(this, "reflection fail", Toast.LENGTH_SHORT).show();
//			e.printStackTrace();
//		}

		if (Build.VERSION.SDK_INT < 28) return;
		try {
			Class clazz = Class.forName("android.app.ActivityThread");
			Method currentActivityThread = clazz.getDeclaredMethod("currentActivityThread");
			currentActivityThread.setAccessible(true);
			Object activityThread = currentActivityThread.invoke(null);
			Field mHiddenApiWarningShown = clazz.getDeclaredField("mHiddenApiWarningShown");
			mHiddenApiWarningShown.setAccessible(true);
			mHiddenApiWarningShown.setBoolean(activityThread, true);
			Log.e("disableAPIDialog", "EEEEEE:ok");
		} catch (Exception e) {
			Log.e("disableAPIDialog", "EEEEEE:" + e.getMessage());
			e.printStackTrace();
		}


	}

	private void initUmeng() {

		//设置Log开关
		//UMConfigure.setLogEnabled(true);

		//初始化组件化基础库, 统计SDK/推送SDK/分享SDK都必须调用此初始化接口
//		UMConfigure.init(this, "59892f08310c9307b60023d0", "Umeng", UMConfigure.DEVICE_TYPE_PHONE,
//				"669c30a9584623e70e8cd01b0381dcb4");
		//PushSDK初始化(如使用推送SDK，必须调用此方法)
		//initUpush();
	}

	private void initTsweb() {
		// 在调用TBS初始化、创建WebView之前进行如下配置
//		HashMap map = new HashMap();
//		map.put(TbsCoreSettings.TBS_SETTINGS_USE_SPEEDY_CLASSLOADER, true);
//		map.put(TbsCoreSettings.TBS_SETTINGS_USE_DEXLOADER_SERVICE, true);
//		QbSdk.initTbsSettings(map);


	}

	private void initApp() {

		// mImageUtil = new ImageUtil();
		//  mConfiguration = new BaseConfiguration();

		//uniqueId = DeviceUtils.getUniqueDeviceId();
		STATUS_BAR_HEIGHT = getStatusBarHeight();

		DisplayMetrics dm = new DisplayMetrics();
		((WindowManager) getApplicationContext()
				.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(dm);

		SCREEN_WIDTH = dm.widthPixels;
		SCREEN_HEIGHT = dm.heightPixels;
		TITLE_BAR_HEIGHT = (int) getResources().getDimension(R.dimen.title_bar_height);


	}

	public int getStatusBarHeight() {
		int result = 0;
		int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
		if (resourceId > 0) {
			result = getResources().getDimensionPixelSize(resourceId);
		}
		return result;
	}

	/**
	 * 为自定义APP实例赋予Crash记录功能
	 */
	private void initCrashHandler() {
		LogReport.getInstance()
				//支持设置缓存大小，超出后清空
				.setCacheSize(30 * 1024 * 1024)
				//定义路径为：sdcard/[app name]/
				.setLogDir(getApplicationContext(), "sdcard/" + getPackageName() + "/")
				//设置只在Wifi状态下上传，设置为false为Wifi和移动网络都上传
				.setWifiOnly(true)
				//支持自定义保存崩溃信息的样式
				.setLogSaver(new CrashWriter(getApplicationContext()))
				//支持日志到AES加密或者DES加密，默认不开启
				//.setEncryption(new AESEncode())
				.init(getApplicationContext());

		if (getHttpReporter() != null) {
			LogReport.getInstance().setUploadType(getHttpReporter());
		}

		//initHttpReporter();
		//开启错误日志上传
		LogReport.getInstance().upload(this);
	}


	/**
	 * 初始化日志框架
	 *
	 * @param logTag 日志 tag
	 */
	private void initLogger(String logTag) {
		Log.e(logTag,"initLogger..");
		Timber.uprootAll();
		Timber.plant(new Timber.DebugTree());
		FormatStrategy formatStrategy = PrettyFormatStrategy.newBuilder()
				.showThreadInfo(true)  // (Optional) Whether to show thread info or not. Default true
				.methodCount(2)         // (Optional) How many method line to show. Default 2
				.methodOffset(7)        // (Optional) Hides internal method calls up to offset. Default 5
				//.logStrategy(customLog) // (Optional) Changes the log strategy to print out. Default LogCat
				.tag(logTag)   // (Optional) Global tag for every log. Default PRETTY_LOGGER
				.build();

		Logger.addLogAdapter(new AndroidLogAdapter(formatStrategy));
		Timber.e("initLogger..");


	}

	/**
	 * 初始化字体
	 */
	private void initFont() {
//		CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
//				.setDefaultFontPath("fonts/xhjt.ttf")
//				.setFontAttrId(R.attr.fontPath)
//				.build()
//		);
	}


	/**
	 * 提供APP实例
	 *
	 * @return
	 */
	public static BaseApplication getInstance() {
		return mBaseApplication;
	}

	//public ImageUtil getImageUtil() {
//		return mImageUtil;
//	}

	//public BaseConfiguration getConfiguration() {
//		return mConfiguration;
//	}

	public Map<String, Integer> getFaceMap() {
		return mFaceMap;
	}

	public ArrayList<String> getFaceString() {
		return mFaceString;
	}

	private void initFaceMap() {

//		mFaceMap.put("[呲牙]", R.drawable.f_static_000);
//		mFaceMap.put("[调皮]", R.drawable.f_static_001);
//		mFaceMap.put("[流汗]", R.drawable.f_static_002);
//		mFaceMap.put("[偷笑]", R.drawable.f_static_003);
//		mFaceMap.put("[再见]", R.drawable.f_static_004);
//		mFaceMap.put("[敲打]", R.drawable.f_static_005);
//		mFaceMap.put("[擦汗]", R.drawable.f_static_006);
//		mFaceMap.put("[猪头]", R.drawable.f_static_007);
//		mFaceMap.put("[玫瑰]", R.drawable.f_static_008);
//		mFaceMap.put("[流泪]", R.drawable.f_static_009);
//		mFaceMap.put("[大哭]", R.drawable.f_static_010);
//		mFaceMap.put("[嘘]", R.drawable.f_static_011);
//		mFaceMap.put("[酷]", R.drawable.f_static_012);
//		mFaceMap.put("[抓狂]", R.drawable.f_static_013);
//		mFaceMap.put("[委屈]", R.drawable.f_static_014);
//		mFaceMap.put("[便便]", R.drawable.f_static_015);
//		mFaceMap.put("[炸弹]", R.drawable.f_static_016);
//		mFaceMap.put("[菜刀]", R.drawable.f_static_017);
//		mFaceMap.put("[可爱]", R.drawable.f_static_018);
//		mFaceMap.put("[色]", R.drawable.f_static_019);
//
//		mFaceMap.put("[害羞]", R.drawable.f_static_020);
//		mFaceMap.put("[得意]", R.drawable.f_static_021);
//		mFaceMap.put("[吐]", R.drawable.f_static_022);
//		mFaceMap.put("[微笑]", R.drawable.f_static_023);
//		mFaceMap.put("[发怒]", R.drawable.f_static_024);
//		mFaceMap.put("[尴尬]", R.drawable.f_static_025);
//		mFaceMap.put("[惊恐]", R.drawable.f_static_026);
//		mFaceMap.put("[冷汗]", R.drawable.f_static_027);
//		mFaceMap.put("[爱心]", R.drawable.f_static_028);
//		mFaceMap.put("[示爱]", R.drawable.f_static_029);
//		mFaceMap.put("[白眼]", R.drawable.f_static_030);
//		mFaceMap.put("[傲慢]", R.drawable.f_static_031);
//		mFaceMap.put("[难过]", R.drawable.f_static_032);
//		mFaceMap.put("[惊讶]", R.drawable.f_static_033);
//		mFaceMap.put("[疑问]", R.drawable.f_static_034);
//		mFaceMap.put("[睡]", R.drawable.f_static_035);
//		mFaceMap.put("[亲亲]", R.drawable.f_static_036);
//		mFaceMap.put("[憨笑]", R.drawable.f_static_037);
//		mFaceMap.put("[爱情]", R.drawable.f_static_038);
//		mFaceMap.put("[衰]", R.drawable.f_static_039);
//
//		mFaceMap.put("[撇嘴]", R.drawable.f_static_040);
//		mFaceMap.put("[阴险]", R.drawable.f_static_041);
//		mFaceMap.put("[奋斗]", R.drawable.f_static_042);
//		mFaceMap.put("[发呆]", R.drawable.f_static_043);
//		mFaceMap.put("[右哼哼]", R.drawable.f_static_044);
//		mFaceMap.put("[拥抱]", R.drawable.f_static_045);
//		mFaceMap.put("[坏笑]", R.drawable.f_static_046);
//		mFaceMap.put("[飞吻]", R.drawable.f_static_047);
//		mFaceMap.put("[鄙视]", R.drawable.f_static_048);
//		mFaceMap.put("[晕]", R.drawable.f_static_049);
//		mFaceMap.put("[大兵]", R.drawable.f_static_050);
//		mFaceMap.put("[可怜]", R.drawable.f_static_051);
//		mFaceMap.put("[强]", R.drawable.f_static_052);
//		mFaceMap.put("[弱]", R.drawable.f_static_053);
//		mFaceMap.put("[握手]", R.drawable.f_static_054);
//		mFaceMap.put("[胜利]", R.drawable.f_static_055);
//		mFaceMap.put("[抱拳]", R.drawable.f_static_056);
//		mFaceMap.put("[凋谢]", R.drawable.f_static_057);
//		mFaceMap.put("[饭]", R.drawable.f_static_058);
//		mFaceMap.put("[蛋糕]", R.drawable.f_static_059);
//
//		mFaceMap.put("[西瓜]", R.drawable.f_static_060);
//		mFaceMap.put("[啤酒]", R.drawable.f_static_061);
//		mFaceMap.put("[飘虫]", R.drawable.f_static_062);
//		mFaceMap.put("[勾引]", R.drawable.f_static_063);
//		mFaceMap.put("[OK]", R.drawable.f_static_064);
//		mFaceMap.put("[爱你]", R.drawable.f_static_065);
//		mFaceMap.put("[咖啡]", R.drawable.f_static_066);
//		mFaceMap.put("[钱]", R.drawable.f_static_067);
//		mFaceMap.put("[月亮]", R.drawable.f_static_068);
//		mFaceMap.put("[美女]", R.drawable.f_static_069);
//		mFaceMap.put("[刀]", R.drawable.f_static_070);
//		mFaceMap.put("[发抖]", R.drawable.f_static_071);
//		mFaceMap.put("[差劲]", R.drawable.f_static_072);
//		mFaceMap.put("[拳头]", R.drawable.f_static_073);
//		mFaceMap.put("[心碎]", R.drawable.f_static_074);
//		mFaceMap.put("[太阳]", R.drawable.f_static_075);
//		mFaceMap.put("[礼物]", R.drawable.f_static_076);
//		mFaceMap.put("[足球]", R.drawable.f_static_077);
//		mFaceMap.put("[骷髅]", R.drawable.f_static_078);
//		mFaceMap.put("[挥手]", R.drawable.f_static_079);
//
//		mFaceMap.put("[闪电]", R.drawable.f_static_080);
//		mFaceMap.put("[饥饿]", R.drawable.f_static_081);
//		mFaceMap.put("[困]", R.drawable.f_static_082);
//		mFaceMap.put("[咒骂]", R.drawable.f_static_083);
//		mFaceMap.put("[折磨]", R.drawable.f_static_084);
//		mFaceMap.put("[抠鼻]", R.drawable.f_static_085);
//		mFaceMap.put("[鼓掌]", R.drawable.f_static_086);
//		mFaceMap.put("[糗大了]", R.drawable.f_static_087);
//		mFaceMap.put("[左哼哼]", R.drawable.f_static_088);
//		mFaceMap.put("[哈欠]", R.drawable.f_static_089);
//		mFaceMap.put("[快哭了]", R.drawable.f_static_090);
//		mFaceMap.put("[吓]", R.drawable.f_static_091);
//		mFaceMap.put("[篮球]", R.drawable.f_static_092);
//		mFaceMap.put("[乒乓球]", R.drawable.f_static_093);
//		mFaceMap.put("[NO]", R.drawable.f_static_094);
//		mFaceMap.put("[跳跳]", R.drawable.f_static_095);
//		mFaceMap.put("[怄火]", R.drawable.f_static_096);
//		mFaceMap.put("[转圈]", R.drawable.f_static_097);
//		mFaceMap.put("[磕头]", R.drawable.f_static_098);
//		mFaceMap.put("[回头]", R.drawable.f_static_099);
//
//		mFaceMap.put("[跳绳]", R.drawable.f_static_100);
//		mFaceMap.put("[激动]", R.drawable.f_static_101);
//		mFaceMap.put("[街舞]", R.drawable.f_static_102);
//		mFaceMap.put("[献吻]", R.drawable.f_static_103);
//		mFaceMap.put("[左太极]", R.drawable.f_static_104);
//		mFaceMap.put("[右太极]", R.drawable.f_static_105);
//		mFaceMap.put("[闭嘴]", R.drawable.f_static_106);
	}

	private void initFaceString() {

		Set<String> set = mFaceMap.keySet();
		mFaceString.addAll(set);
	}

	//	HttpReporter http = new HttpReporter(this);
//		http.setUrl("http://crashreport.jd-app.com/your_receiver");//发送请求的地址
//		http.setFileParam("fileName");//文件的参数名
//		http.setToParam("to");//收件人参数名
//		http.setTo("你的接收邮箱");//收件人
//		http.setTitleParam("subject");//标题
//		http.setBodyParam("message");//内容
//		LogReport.getInstance().setUploadType(http);
	public abstract HttpReporter getHttpReporter();
}
